#include "Color.h"

const Color<float> Color<float>::BLACK( 0.0, 0.0, 0.0 );
const Color<float> Color<float>::WHITE( 1.0, 1.0, 1.0 );

template <class Real>
Color<Real>::Color()
{
}

template<class Real>
Color<Real>::Color( Real mr, Real mg, Real mb )
{
	r = mr;
	g = mg;
	b = mb;
}

template<class Real>
Real& Color<Real>::operator [] ( int i ) const
{
	return (Real&) *(&r + i);
}


template <class Real>
Color<Real>::operator Real * ()
{
	return &r;
}

template<class Real>
void Color<Real>::clamp()
{
	if ( r < 0.0 )
		r = 0.0;
	else if ( r > 1.0 )
		r = 1.0;

	if ( g < 0.0 )
		g = 0.0;
	else if ( g > 1.0 )
		g = 1.0;

	if ( b < 0.0 )
		b = 0.0;
	else if ( b > 1.0 )
		b = 1.0;
}

template<class Real>
void Color<Real>::scale_by_max()
{
	Real max = r;
	if ( g > max )
		max = g;
	if ( b > max )
		max = b;

	if ( max > 1.0 )
	{
		Real inv_max = 1.0 / max;
		r *= inv_max;
		g *= inv_max;
		b *= inv_max;
	}
}

template<class Real>
Color<Real>& Color<Real>::operator= ( const Color<Real>& color )
{
	r = color.r;
	g = color.g;
	b = color.b;
	return *this;
}

template<class Real>
bool Color<Real>::operator == ( const Color<Real>& color ) const
{
	return r == color.r
		&& g == color.g
		&& b == color.b;
}

template<class Real>
bool Color<Real>::operator != ( const Color<Real>& color ) const
{
	return r != color.r
		&& g != color.g
		&& b != color.b;
}

template<class Real>
Color<Real> Color<Real>::operator + ( const Color<Real>& color ) const
{
	return Color(r + color.r, g + color.g, b + color.b );
}

template<class Real>
Color<Real> Color<Real>::operator - ( const Color<Real>& color ) const
{
	return Color(r - color.r, g - color.g, b - color.b );
}

template<class Real>
Color<Real> Color<Real>::operator * ( const Color<Real>& color ) const
{
	return Color(r * color.r, g * color.g, b * color.b );
}

template<class Real>
Color<Real> Color<Real>::operator / ( const Color<Real>& color ) const
{
	assert( color.r > 0.0
		&&  color.g > 0.0
		&&  color.b > 0.0 );

	return Color<Real>(r / color.r, g / color.g, b / color.b );
}

template<class Real>
Color<Real> Color<Real>::operator- () const
{
	return Color( -r, -g, -b );
}

template<typename Real>
Color<Real>operator* ( Real scalar, const Color<Real>& color ) const
{
	return Color<Real>( scalar * color.r, scalar * color.g, scalar * color.b );
}

template<class Real>
Color<Real>& Color<Real>::operator += ( const Color<Real>& color ) 
{
	r += color.r;
	g += color.g;
	b += color.b;

	return *this;
}

template<class Real>
Color<Real>& Color<Real>::operator -= ( const Color<Real>& color ) 
{
	r -= color.r;
	g -= color.g;
	b -= color.b;

	return *this;
}

template<class Real>
Color<Real>& Color<Real>::operator *= ( const Color<Real>& color ) 
{
	r *= color.r;
	g *= color.g;
	b *= color.b;

	return *this;
}

template<class Real>
Color<Real>& Color<Real>::operator /= ( const Color<Real>& color ) 
{
	assert( color.r > 0.0
		&&  color.g > 0.0
		&&  color.b > 0.0 );

	r /= color.r;
	g /= color.g;
	b /= color.b;

	return *this;
}

